從Winform要轉Webform,或從ASP要轉ASP.NET,寫網頁幾乎一定用的到的東西,「如何執行一段javascript」。
這邊舉了8+1種例子,各有好壞,在最一般的使用狀況下,這9種都可以跑,但是不一定適合,有的在特定狀況下會出現js error,有的會有效率的問題。所以得知道什麼樣的方式,最合適目前的狀況。
內容裡面的九種方式,其實在大部分的情況都可以用,但是用錯了潛在的問題很多,有可能只是沒測到,有可能只是剛好沒發生問題, 一定要謹慎使用,用對時機。
PS:因為內容太長,無法塞在內容裡面,所以把問題拉到描述這邊。
最後,請想學習的客倌,看完這篇文章思考一下,下列的問題該如何回答:
1.如何在Server端註冊一段JavaScript,讓網頁可以執行?
2.為什麼這樣註冊,網頁上就可以執行這段JavaScript?(hint: JavaScript存在哪裡)
3.當畫面上有使用UpdatePanel時,該用什麼樣的方式註冊JavaScript?
4.JavaScript要Render在哪,效率才會比較好?
5.要怎麼樣動態的改變JavaScript的include或內容?
6.Response.Write()會有什麼問題?
8種例子
**1.Hard-code include js file in **
在區塊裡面hard-code寫死引用的js檔,引用後,可以直接使用該js裡面的function
<head runat="server">
<title>怎麼註冊javascript</title>
<script src="InCludeJScript.js" type="text/javascript"></script>
**2.Hard-code js functin in **
在區塊裡面hard-code寫死的javascript,在頁面裡面可以直接呼叫,
值得注意的是,若不是一開始就要執行的javascript,應該放到以後,如果在這邊的內容太多, 會導致loading時間過長,對user來說,body裡的內容才是「網頁內容」,就可能造成user認為網頁效率很慢的錯覺。
而且放在這個區塊如果是一開始就執行,會讀不到body裡面的DOM,因為內容還沒Render出來, 例如alert(document.getElementById(‘form1’)); 會是null。
<head runat="server">
<title>怎麼註冊javascript</title>
<script type="text/javascript">
alert('head的時候,form為'+document.getElementById('form1'));
//head裡面應該是放一些load進來就要執行的js,如果是供user觸發事件才要執行的,可以放在bottom
function inhead() {
alert('call js in head');
}
</script>
**3.Hard-code js functin after **
放在以後 hard-code寫死的javascript,這個時候alert(document.getElementById(‘form1’)); 就是[object]
<script type="text/javascript">
alert('bottom的時候,form為'+document.getElementById('form1'));
//如果不是一開始就用的到的js,記得放在bottom,這樣子網頁載入對使用者來講,才會覺得快
function inbottom() {
alert('call js in bottom');
}
</script>
4.Control Attribute.Add in server
在Server端替Control加上Attribute,attribute為事件,內容為javascript, 只要加過一次,textbox會幫忙記住,postback之後仍然會存在
/// <summary>
/// 在DOM上面直接加上屬性與要執行的javascript,只要加一次,postback仍然存在
/// </summary>
private void AddingAttributeOnDOM()
{
this.TextBox1.Attributes.Add("onchange", "alert('textbox onchange');");
}
5.ClientScript.RegisterStartupScript
在Server執行結束後,要執行的javascript,使用RegisterStartupScript,若畫面有ScriptManager,要記得透過ScriptManager註冊
/// <summary>
/// Render結束後要執行的javascript,有ScriptManager的話要透過ScriptManager註冊
/// </summary>
private void RegisterStartupScript()
{
if (ScriptManager.GetCurrent(this.Page) == null)
{
Page.ClientScript.RegisterStartupScript(this.Page.GetType(), "buttonStartup", "alert('Page.ClientScript.RegisterStartupScript');", true);
}
else
{
ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "buttonStartupBySM", "alert('ScriptManager.RegisterStartupScript');", true);
}
}
6.ClientScript.RegisterClientScriptBlock
在Server端,要註冊js到網頁的最前面,(其實是body之後的最前面),透過RegisterClientScriptBlock(),一樣要透過ScriptManager
/// <summary>
/// 要Render在body裡面最前面的js
/// </summary>
private void RegisterClientScriptBlock()
{
string blcokjs = @"function RegisterClientScriptBlock(){ alert('RegisterClientScriptBlock'); }";
if (ScriptManager.GetCurrent(this.Page) == null)
{
Page.ClientScript.RegisterClientScriptBlock(this.Page.GetType(), "block", blcokjs, true);
}
else
{
ScriptManager.RegisterClientScriptBlock(this.Page, this.Page.GetType(), "block", blcokjs, true);
}
}
7.Include js file by Page.Header.Controls.Add in server
Server端使用Page.Header.Controls.Add的方式,把js include在head區塊裡,每次load都要加,否則postback會掉
/// <summary>
/// 要每次Page Load都加入這段到head區塊裡
/// </summary>
private void addHeaderControl()
{
HtmlGenericControl objjQuery = new HtmlGenericControl("script");
objjQuery.Attributes.Add("language", "javascript");
objjQuery.Attributes.Add("src", "HeaderControlJS.js");
this.Page.Header.Controls.Add(objjQuery);
}
8.ClientScript.RegisterClientScriptInclude
Server端使用RegisterClientScriptInclude來動態引入js檔,也是每次load都要加,否則postback之後原始碼上就不會有這引入這段js
/// <summary>
/// 在server端include js,有Scriptmanager要透過Scriptmanager控制
/// 要每次Page Load都註冊,才會存在原始碼,postback才不會掉
/// </summary>
private void PageClientInclude()
{
if (ScriptManager.GetCurrent(this.Page) == null)
{
Page.ClientScript.RegisterClientScriptInclude("PageClientInclude", "PageClientInclude.js");
}
else
{
ScriptManager.RegisterClientScriptInclude(this.Page, this.Page.GetType(), "PageClientInclude", "PageClientInclude.js");
}
}
注意注意
在ASP.NET Webform中要執行一段JavaScript,不要再使用的一種方式,Response.Write(),這會導致webform畫面上的CSS失去作用,且有UpdatePanel的時候會有js error。
/// <summary>
/// 在ASP.NET裡,請不要再用下面的程式碼,因為會有兩個問題
/// 1.導致頁面的CSS失去作用
/// 2.如果畫面上有Scriptmanager+UpdatePanel,會出現exception
/// 請改寫成RegisterStartupScript()的方式
/// </summary>
private void CallJSbyResponse()
{ Response.Write(@"<script>alert('I am Response.write');</script>"); }
另外,附上一張重要的圖,是最後Render到畫面上的原始碼,因應使用方式不同,js擺放在不同的位置。